3 // Copyright (C) 2005 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
32 // Permission to use, copy, modify, sell, and distribute this software
33 // is hereby granted without fee, provided that the above copyright
34 // notice appears in all copies, and that both that copyright notice and
35 // this permission notice appear in supporting documentation. None of
36 // the above authors, nor IBM Haifa Research Laboratories, make any
37 // representation about the suitability of this software for any
38 // purpose. It is provided "as is" without express or implied warranty.
41 * @file order_statistics_imp.hpp
42 * Contains forward declarations for order_statistics_key
45 #ifndef ORDER_STATISTICS_IMP_HPP
46 #define ORDER_STATISTICS_IMP_HPP
48 #define PB_ASSOC_CLASS_T_DEC \
49 template<class Key, class Allocator>
51 #define PB_ASSOC_CLASS_C_DEC \
52 order_statistics_key< \
58 PB_ASSOC_CLASS_C_DEC::
59 order_statistics_key(const_key_reference r_key) :
66 PB_ASSOC_CLASS_C_DEC::
67 operator typename PB_ASSOC_CLASS_C_DEC::key_reference()
74 PB_ASSOC_CLASS_C_DEC::
75 operator typename PB_ASSOC_CLASS_C_DEC::key_type() const
80 #undef PB_ASSOC_CLASS_T_DEC
82 #undef PB_ASSOC_CLASS_C_DEC
84 #define PB_ASSOC_CLASS_T_DEC \
85 template<class Cmp_Fn, class Allocator>
87 #define PB_ASSOC_CLASS_C_DEC \
88 order_statistics_key_cmp< \
94 PB_ASSOC_CLASS_C_DEC::
95 order_statistics_key_cmp()
100 PB_ASSOC_CLASS_C_DEC::
101 order_statistics_key_cmp(const Cmp_Fn& r_cmp_fn) :
107 PB_ASSOC_CLASS_C_DEC::
108 operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const
110 return Cmp_Fn::operator()((key_type)r_lhs_key, (key_type)r_rhs_key);
114 inline typename PB_ASSOC_CLASS_C_DEC::cmp_fn&
115 PB_ASSOC_CLASS_C_DEC::
122 inline const typename PB_ASSOC_CLASS_C_DEC::cmp_fn&
123 PB_ASSOC_CLASS_C_DEC::
129 #undef PB_ASSOC_CLASS_T_DEC
131 #undef PB_ASSOC_CLASS_C_DEC
133 #define PB_ASSOC_CLASS_T_DEC \
134 template<class Key, class Allocator>
136 #define PB_ASSOC_CLASS_C_DEC \
137 order_statistics_node_updator< \
143 PB_ASSOC_CLASS_C_DEC::
144 operator()(const_key_pointer p_key, const_key_pointer p_l_child_key, const_key_pointer p_r_child_key)
147 * The left rank is 0 if there is no left child,
148 * or the rank of the left child, otherwise.
150 const size_type l_rank =(p_l_child_key == NULL)? 0 : p_l_child_key->m_rank;
153 * The right rank is 0 if there is no right child,
154 * or the rank of the right child, otherwise.
156 const size_type r_rank =(p_r_child_key == NULL)? 0 : p_r_child_key->m_rank;
159 * The rand of the entry is the sumb of the ranks of its
160 * children + 1 (for itself).
162 p_key->m_rank = 1 + l_rank + r_rank;
167 PB_ASSOC_CLASS_C_DEC::
168 swap(PB_ASSOC_CLASS_C_DEC& /*r_other*/)
171 #undef PB_ASSOC_CLASS_T_DEC
173 #undef PB_ASSOC_CLASS_C_DEC
175 #define PB_ASSOC_CLASS_T_DEC \
176 template<class Cntnr>
178 #define PB_ASSOC_CLASS_C_DEC \
183 inline typename PB_ASSOC_CLASS_C_DEC::iterator
184 PB_ASSOC_CLASS_C_DEC::
185 operator()(Cntnr& r_c, size_type order) const
187 return find(r_c, order);
191 inline typename PB_ASSOC_CLASS_C_DEC::const_iterator
192 PB_ASSOC_CLASS_C_DEC::
193 operator()(const Cntnr& r_c, size_type order) const
195 return find(r_c, order);
199 inline typename PB_ASSOC_CLASS_C_DEC::const_iterator
200 PB_ASSOC_CLASS_C_DEC::
201 find(const Cntnr& r_c, size_type order)
203 if (order > r_c.size())
207 * Start at the top of the tree.
209 typename Cntnr::const_node_iterator it = r_c.node_begin();
214 while (it != r_c.node_end())
216 typename Cntnr::const_node_iterator l_it = it.l_child();
219 * The order of the element, o, is the rank of the left
220 * child (for the entry itself).
222 const size_type o = (l_it == r_c.node_end())?
226 * If the current order, o, is the order requested,
227 * the key has been found.
232 * If the current order, o, is larger than the order requested,
233 * we should move to the left subtree.
238 * Otherwise adujst the requested order and move to the right subtree.
252 inline typename PB_ASSOC_CLASS_C_DEC::iterator
253 PB_ASSOC_CLASS_C_DEC::
254 find(Cntnr& r_c, size_type order)
256 if (order > r_c.size())
260 * Start at the top of the tree.
262 typename Cntnr::node_iterator it = r_c.node_begin();
267 while (it != r_c.node_end())
269 typename Cntnr::node_iterator l_it = it.l_child();
272 * The order of the element, o, is the rank of the left
273 * child (for the entry itself).
275 const size_type o = (l_it == r_c.node_end())?
277 r_c.extract_key(*(*l_it)).m_rank;
280 * If the current order, o, is the order requested,
281 * the key has been found.
286 * If the current order, o, is larger than the order requested,
287 * we should move to the left subtree.
292 * Otherwise adujst the requested order and move to the right subtree.
305 #undef PB_ASSOC_CLASS_T_DEC
307 #undef PB_ASSOC_CLASS_C_DEC
309 #define PB_ASSOC_CLASS_T_DEC \
310 template<class Cntnr>
312 #define PB_ASSOC_CLASS_C_DEC \
317 inline typename PB_ASSOC_CLASS_C_DEC::size_type
318 PB_ASSOC_CLASS_C_DEC::
319 operator()(const Cntnr& r_c, const underlying_key_type& r_key) const
322 * The logic here is similar to that in order_by_key.
325 typename Cntnr::const_node_iterator it = r_c.node_begin();
329 while (it != r_c.node_end())
331 typename Cntnr::const_node_iterator l_it = it.l_child();
333 if (r_c.get_cmp_fn().get_cmp_fn()(
335 r_c.extract_key(*(*it)).m_key))
337 else if (r_c.get_cmp_fn().get_cmp_fn()(
338 r_c.extract_key(*(*it)).m_key,
342 ord += (l_it == r_c.node_end())?
344 1 + r_c.extract_key(*(*l_it)).m_rank;
350 ord += (l_it == r_c.node_end())?
352 r_c.extract_key(*(*l_it)).m_rank;
361 #undef PB_ASSOC_CLASS_T_DEC
363 #undef PB_ASSOC_CLASS_C_DEC
365 #define PB_ASSOC_CLASS_T_DEC \
366 template<class Cntnr, class Allocator>
368 #define PB_ASSOC_CLASS_C_DEC \
369 order_statistics_key_verifier< \
373 template<class Cntnr, class Allocator = std::allocator<char> >
374 class order_statistics_key_verifier
379 typedef Allocator allocator;
381 typedef typename allocator::size_type size_type;
384 typename allocator::template rebind<map>::other::const_reference
389 operator()(const Cntnr& r_c) const;
392 typedef typename Cntnr::const_node_iterator const_node_iterator;
394 typedef typename Cntnr::const_iterator cntnr_const_it;
396 typedef std::pair<bool, size_type> stat;
400 verify_imp(const_node_iterator it, const_node_iterator end_it)
403 return (std::make_pair(true, 0));
406 verify_imp(it.l_child(), end_it);
409 verify_imp(it.r_child(), end_it);
411 if (!l_ret.first || !r_ret.first)
412 return (std::make_pair(false, 0));
414 if ((*it)->m_rank != 1 + l_ret.second + r_ret.second)
415 return (std::make_pair(false, 0));
417 return (std::make_pair(true, (*it)->m_rank));
423 PB_ASSOC_CLASS_C_DEC::
424 operator()(const Cntnr& r_c) const
426 const stat top_stat =
427 verify_imp(r_c.node_begin(), r_c.node_end());
429 return (top_stat.first);
432 #undef PB_ASSOC_CLASS_T_DEC
434 #undef PB_ASSOC_CLASS_C_DEC
436 #endif // #ifndef ORDER_STATISTICS_IMP_HPP